package org.example.java.util.concurrency.threadlocal;

import java.lang.reflect.Field;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Created by Juntao.Zhang on 2014/9/9.
 */
public class SequenceNumber {
  //①通过匿名内部类覆盖ThreadLocal的initialValue()方法，指定初始值
  private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
    public Integer initialValue() {
      return 0;
    }
  };
//  private static ThreadLocal<Integer> seqNum1 = new ThreadLocal<Integer>() {
//    public Integer initialValue() {
//      return 10;
//    }
//  };

  //②获取下一个序列值
  public int getNextNum() {
    seqNum.set(seqNum.get() + 1);
//    seqNum1.set(seqNum1.get() + 1);
    return seqNum.get();
  }

  public static void main(String[] args) {
    SequenceNumber sn = new SequenceNumber();
    //③ 3个线程共享sn，各自产生序列号
    TestClient t1 = new TestClient(sn);
    TestClient t2 = new TestClient(sn);
    TestClient t3 = new TestClient(sn);
    t1.start();
    t2.start();
    t3.start();

    seqNum.remove();
  }

  static class TestClient extends Thread {
    private SequenceNumber sn;

    public TestClient(SequenceNumber sn) {
      this.sn = sn;
    }

    public void run() {
      for (int i = 0; i < 3; i++) {//④每个线程打出3个序列值
        System.out.println("thread[" + Thread.currentThread().getName() + "] sn[" + sn.getNextNum() + "]");
        try {
          try {
            Field field = Thread.class.getDeclaredField("threadLocals");
            field.setAccessible(true);
            System.out.println(Thread.currentThread().getName()+" "+field.get(this));
//            System.gc();
//            System.out.println(Thread.currentThread().getName()+" "+field.get(this));
          } catch (Exception e) {
            e.printStackTrace();
          }
          TimeUnit.MILLISECONDS.sleep(new Random(20).nextInt());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
}
